﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Day3
{
    class Program
    {
        static void Main(string[] args)
        {
            demo1();
            demo2();
            demo3();
            demo4();
            demo5();
            demo6();
            demo7();
        }

        #region demo1
        /// <summary>
        /// 创建任务的两种方式
        /// </summary>
        private static void demo1()
        {
            Task task1 = new Task(() =>
            {
                Console.WriteLine("Hello, Task");
            });
            task1.Start();
            Task task2 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Hello, task started by factory");
            });
            Console.ReadLine();
        }
        #endregion

        #region demo2 查看任务的生命周期
        private static void demo2()
        {
            Task task = new Task(() =>
            {
                Console.WriteLine("Begin");
                Thread.Sleep(2000);
                Console.WriteLine("Finish");
            });
            Console.WriteLine($"Before start:{task.Status}");
            task.Start();
            Console.WriteLine($"After start:{task.Status}");
            task.Wait(); // task1.Wait();就是等待任务执行完成，我们可以看到最后task的状态变为Completed
            Console.WriteLine($"After finish:{task.Status}");
            Console.ReadLine();
        }
        #endregion

        #region demo3 Task的任务控制
        /// <summary>
        /// Task最吸引人的地方就是他的任务控制了，你可以很好的控制task的执行顺序，让多个task有序的工作
        /// </summary>
        private static void demo3()
        {
            // Task.WaitAll,等待所有的任务都执行完成
            Task task1 = new Task(() =>
            {
                Console.WriteLine("task 1 begin");
                Thread.Sleep(2000);
                Console.WriteLine("task 1 finish");
            });
            Task task2 = new Task(() =>
            {
                Console.WriteLine("task 2 begin");
                Thread.Sleep(3000);
                Console.WriteLine("task 2 finish");
            });
            task1.Start();
            task2.Start();
            Task.WaitAll(task1, task2);
            Console.WriteLine("All task finished");
            Console.ReadLine();
        }
        #endregion

        #region demo4 WaitAny
        private static void demo4()
        {
            // Task.WaitAny等待任何一个任务完成就继续向下执行
            Task task1 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("task 1 begin");
                Thread.Sleep(2000);
                Console.WriteLine("task 1 finish");
            });
            Task task2 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("task 2 begin");
                Thread.Sleep(3000);
                Console.WriteLine("task 2 finish");
            });
            Task.WaitAny(task1, task2);
            Console.WriteLine("All task finished");
            Console.ReadLine();
        }
        #endregion

        #region demo5 ContinueWith
        private static void demo5()
        {
            // ContinueWith,在第一个Task完成后自动启动下一个Task，实现Task的延续
            Task task1 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("task 1 begin");
                Thread.Sleep(2000);
                Console.WriteLine("task 1 finish");
            });
            Task task2 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("task 2 begin");
                Thread.Sleep(3000);
                Console.WriteLine("task 2 finish");
                return "task2";
            }).ContinueWith((p) => {
                Console.WriteLine(p.Result);
            });
            var result = task1.ContinueWith<string>((task) =>
            {
                Console.WriteLine("task 1 finished");
                return "This is task result";
            });
            Console.WriteLine(result.Result.ToString());
            Console.ReadLine();
        }
        #endregion

        #region demo6
        /// <summary>
        /// 在每次调用ContinueWith方法时，每次会把上次Task的引用传入进来，以便检测上次Task的状态，比如我们可以使用上次Task的Result属性来获取返回值
        /// </summary>
        private static void demo6()
        {
            var SendFeedBackTask = Task.Factory.StartNew(() => { Console.WriteLine("Get some data"); })
                .ContinueWith<bool>((s) => { return true; }).ContinueWith<string>((r) =>
                {
                    if (r.Result)
                    {
                        return "Finished";
                    }
                    else
                    {
                        return "Error";
                    }
                });
            Console.WriteLine(SendFeedBackTask.Result);
            Console.ReadLine();
        }
        #endregion

        #region demo7
        /// <summary>
        /// Task的取消
        /// </summary>
        private static void demo7()
        {
            var tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;
            // 启动一个task
            Task task = Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 1000; i++)
                {
                    Thread.Sleep(1000);
                    if (token.IsCancellationRequested)
                    {
                        Console.WriteLine("Abort mission success");
                        return;
                    }
                }
            }, token);
            // 给token注册了一个方法
            token.Register(() =>
            {
                Console.WriteLine("Canceled");
            });
            Console.WriteLine("Press any key to cancel task...");
            Console.ReadKey(); // 等待用户输入
            tokenSource.Cancel(); // 取消任务
            Console.ReadLine();
        }
        #endregion
    }
}
